#ifndef _PHC_LIB_H
#define _PHC_LIB_H

/* only for phc module */
#ifdef PHC_VERSION

#ifdef PDEBUG
#  undef PDEBUG
#endif
#if defined(DEBUG) || defined(PHC_DEBUG)
#  define PDEBUG(fmt, ...)  pr_info("phc: " fmt, ##__VA_ARGS__)
#else
#  define PDEBUG(fmt, ...) pr_debug("phc: " fmt, ##__VA_ARGS__) 
#endif
#define PDEBUG_IO(fmt, ...)
#define PDEBUG_TTY(fmt, ...)
#define PDEBUG_VC(fmt, ...)

#define PINFO(fmt, ...) pr_info("phc: " fmt, ##__VA_ARGS__)
#define PWARN(fmt, ...) pr_warn("phc: warning: " fmt, ##__VA_ARGS__)
#define PERR(fmt, ...) pr_err("phc err:" fmt, ##__VA_ARGS__)


/* phc_dev flags per port */
#define FLAG_IRQ_OFF		0
#define FLAG_WAS_IRQ 		1
#define FLAG_WORKER_PENDING 	2
#define FLAG_NOBFCHECK		3
#define FLAG_CHARMAP_DISABLED	4
#define FLAG_CURSOR_ON		5

#define CRLF 0
#define NPAR 16
#define VC_SCREENBUF_SIZE 200

struct phc_vc_data {
	int open_count;	
	struct mutex mutex; /* locks this struct */
	struct tty_struct *tty;
	
	unsigned long flags;
	unsigned int mcr; /* tiocmget and tiocmset */
	
	unsigned short  vc_num;                 /* Console number */
        unsigned int    vc_cols;                /* [#] Console size */
        unsigned int    vc_rows;
        unsigned int    vc_scan_lines;          /* # of scan lines */
        unsigned long   vc_origin;              /* [!] Start of real screen */
        unsigned long   vc_scr_end;             /* [!] End of real screen */
        unsigned int    vc_top, vc_bottom;      /* Scrolling region */
        unsigned char  *vc_screenbuf;          /* In-memory character/attribute buffer */
        unsigned int    vc_screenbuf_size;
        unsigned char   vc_mode;                /* KD_TEXT, ... */
        /* cursor */
        unsigned int    vc_x, vc_y;             /* Cursor position */
        /* VT terminal data */
        unsigned int    vc_state;               /* Escape sequence parser state */
        unsigned int    vc_npar,vc_par[NPAR];   /* Parameters of current escape sequence */
        /* mode flags */
        unsigned int    vc_charset      : 1;    /* Character set G0 / G1 */
        unsigned int    vc_s_charset    : 1;    /* Saved character set */
        unsigned int    vc_disp_ctrl    : 1;    /* Display chars < 32? */
        unsigned int    vc_toggle_meta  : 1;    /* Toggle high bit? */
        unsigned int    vc_decscnm      : 1;    /* Screen Mode */
        unsigned int    vc_decom        : 1;    /* Origin Mode */
        unsigned int    vc_decawm       : 1;    /* Autowrap Mode */
        unsigned int    vc_deccm        : 1;    /* Cursor Visible */
        unsigned int    vc_decim        : 1;    /* Insert Mode */
        unsigned int    vc_deccolm      : 1;    /* 80/132 Column Mode */
        /* misc */
        unsigned int    vc_ques         : 1;
        unsigned int    vc_need_wrap    : 1;
        unsigned int    vc_tab_stop[8];         /* Tab stops. 256 columns. */
        unsigned int    vc_resize_user;         /* resize request from user */
        unsigned char vc_video_erase_char;
};

struct phclcd_t {
	unsigned int cur_x, cur_y; /* cursor position in this lcd */
	unsigned char cgram[8][8];
};

struct phcdev_t {
	struct pardevice *pd;
	struct phclcd_t *lcd; /* info about every single lcd */
	
	unsigned long flags; /* flags per port */
	
	unsigned char *state; /* what displays lcds */
	unsigned int screen_size; /* size state */
	unsigned int cur_x, cur_y; /* displayed cursor position */
	unsigned int cursor_on; /* on whitch lcd cursor is on; <0 means no cursor */
	
	struct delayed_work work; /* works for irq buffering */
	short int irq_buff;
	short int status; /* current irq getted status */
	/* counters */
	unsigned long int reset_num;
	unsigned long int next_num;
	unsigned long int write_num;
	unsigned long int read_num;
	unsigned long int bfchecks_num;
};

void phc_dev_init(struct phcdev_t *phcdev) 
{
	phcdev->pd = NULL;
	phcdev->lcd = NULL;
	/* initialization of delayed work i leaved in lcdmod.c */
	phcdev->reset_num = 0;
	phcdev->next_num = 0;
	phcdev->read_num = 0;
	phcdev->write_num = 0;
	phcdev->bfchecks_num = 0;
	phcdev->flags = 0;
	phcdev->irq_buff = 0;
	phcdev->status = 0;
	phcdev->cur_x = 0;
	phcdev->cur_y = 0;
	phcdev->cursor_on = -1;
	phcdev->screen_size = 0;
	phcdev->state = NULL;
}

void phc_lcd_init(struct phclcd_t *lcd) 
{
	memset(lcd->cgram, 0, sizeof(char) * 64);
	lcd->cur_x = 0;
	lcd->cur_y = 0;
}

#endif /* ifdef _PHC_VERSION_ */

#endif /* ifdef _PHC_LIB_H_ */
